package com.zsj.comminlibrary.util;

import android.content.ContentResolver;
import android.content.Context;
import android.database.Cursor;
import android.media.MediaMetadataRetriever;
import android.net.Uri;
import android.os.Environment;
import android.provider.MediaStore;

import com.zsj.comminlibrary.base.BaseApplication;

import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.FilenameFilter;
import java.io.IOException;
import java.io.InputStream;
import java.text.DecimalFormat;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.Comparator;
import java.util.List;


public class FileUtil {

    public static final String DOWNLOAD_DIR = "download";
    public static final String ROOT_DIR = "Android/data/";

    /**
     * 获取下载目录
     */
    public static String getDownloadDir() {
        return getDir(DOWNLOAD_DIR);
    }

    /**
     * 获取应用目录，当SD卡存在时，获取SD卡上的目录，当SD卡不存在时，获取应用的cache目录
     */
    public static String getDir(String name) {
        StringBuilder sb = new StringBuilder();
        if (isSDCardAvailable()) {
            sb.append(getExternalStoragePath());
        } else {
            sb.append(getCachePath());
        }
        sb.append(name);
        sb.append(File.separator);
        String path = sb.toString();
        if (createDirs(path)) {
            return path;
        } else {
            return null;
        }
    }
    /**
     * 创建文件夹
     */
    public static boolean createDirs(String dirPath) {
        File file = new File(dirPath);
        if (!file.exists() || !file.isDirectory()) {
            return file.mkdirs();
        }
        return true;
    }

    /**
     * 获取SD下的应用目录
     */
    public static String getExternalStoragePath() {
        StringBuilder sb = new StringBuilder();
        sb.append(Environment.getExternalStorageDirectory().getAbsolutePath());
        sb.append(File.separator);
        sb.append(ROOT_DIR);
        sb.append(File.separator);
        return sb.toString();
    }

    /**
     * 获取应用的cache目录
     */
    public static String getCachePath() {
        File f = BaseApplication.getContext().getCacheDir();
        if (null == f) {
            return null;
        } else {
            return f.getAbsolutePath() + "/";
        }
    }

    /**
     * 判断SD卡是否挂载
     */
    public static boolean isSDCardAvailable() {
        if (Environment.MEDIA_MOUNTED.equals(Environment
                .getExternalStorageState())) {
            return true;
        } else {
            return false;
        }
    }

    /**
     *
     */
    public static ArrayList<File> allFileDirectory = new ArrayList<File>();

    /**
     *
     */
    public static ArrayList<File> allFile = new ArrayList<File>();

    public static boolean isExist(String filename) {
        File file = new File(filename);
        if (!file.exists()) {
            return false;
        }
        return true;
    }

    /**
     * @return
     */
    public static boolean ExistSDCard() {
        if (android.os.Environment.getExternalStorageState().equals(android.os.Environment.MEDIA_MOUNTED)) {
            return true;
        } else
            return false;
    }


    public static File getFile(String filePath, String fileName) {
        if (ExistSDCard()) {
            File fileDir = new File(filePath);
            if (!isExist(filePath)) {
                fileDir.mkdirs();
            }
            return new File(filePath, fileName);
        } else {
            return null;
        }
    }



    public static boolean createFile(String filePath) {
        if (ExistSDCard()) {
            File fileDir = new File(filePath);
            if (!isExist(filePath)) {
                fileDir.mkdirs();
            }
            return isExist(filePath);
        }
        return false;
    }


    public static File getFile(String filePath) {
        if (ExistSDCard())
            return new File(filePath);
        else
            return null;
    }

    @SuppressWarnings("resource")
    public static void saveBinaryFile(String path, String name, byte[] buffer)
            throws IOException {
        //        if(FileUtil.isSDCARDMounted()){
        //            baseDirectory = new File(Environment.getExternalStorageDirectory(), dirPath);
        //        }else{
        //            baseDirectory = new File(dirPath);
        //        }
        File fileDir = new File(path);
        if (!isExist(path)) {
            fileDir.mkdirs();
        }
        File file = new File(fileDir, name);
        FileOutputStream fos;
        fos = new FileOutputStream(file);
        fos.write(buffer);
        fos.flush();
        fos.close();
    }

    public static byte[] toByteArray(InputStream inputStream) {
        try {
            byte[] buffer = new byte[inputStream.available()];
            inputStream.read(buffer);
            inputStream.close();
            return buffer;
        } catch (IOException e) {
            e.printStackTrace();
        }
        return null;
    }

    @SuppressWarnings("resource")
    public static void saveBinaryFile_append(String path, String name, byte[] buffer)
            throws IOException {
        //        if(FileUtil.isSDCARDMounted()){
        //            baseDirectory = new File(Environment.getExternalStorageDirectory(), dirPath);
        //        }else{
        //            baseDirectory = new File(dirPath);
        //        }

        File fileDir = new File(path);
        if (!isExist(path)) {
            fileDir.mkdirs();
        }
        File file = new File(fileDir, name);
        FileOutputStream fos;
        fos = new FileOutputStream(file, true);
        fos.write(buffer);
        fos.flush();
        fos.close();
    }

    public static String getMimeType(String filePath) {
        MediaMetadataRetriever mmr = new MediaMetadataRetriever();
        String mime = "*/*";
        if (filePath != null) {
            try {
                mmr.setDataSource(filePath);
                mime = mmr.extractMetadata(MediaMetadataRetriever.METADATA_KEY_MIMETYPE);
            } catch (IllegalStateException e) {
                return mime;
            } catch (IllegalArgumentException e) {
                return mime;
            } catch (RuntimeException e) {
                return mime;
            }
        }
        return mime;
    }

//    public static byte[] readFile(String filePath) {
//        ByteArrayBuffer bb = new ByteArrayBuffer(512);
//        File file = new File(filePath);
//        FileInputStream input = null;
//        try {
//            input = new FileInputStream(file);
//            byte[] buffer = new byte[512];
//            int len = 0;
//            while ((len = input.read(buffer)) != -1) {
//                bb.append(buffer, 0, len);
//            }
//            input.close();
//        } catch (FileNotFoundException e) {
//            e.printStackTrace();
//        } catch (IOException e) {
//            e.printStackTrace();
//        }
//        return bb.toByteArray();
//    }


    public static void deleteFile(File file) {
        if (file.isFile()) {
            file.delete();
            return;
        }
        if (file.isDirectory()) {
            File[] childFile = file.listFiles();
            if (childFile == null || childFile.length == 0) {
                file.delete();
                return;
            }
            for (File f : childFile) {
                deleteFile(f);
            }
            file.delete();
        }
    }

    public static int hasCache(long userId) {
        //        File file = new File(RunDataUtil.ROUTE_CACHE_PATH + "/" + userId);
        //        if (isExistFile(RunDataUtil.ROUTE_CACHE_PATH + "/" + userId) && file.listFiles().length > 0) {
        //            return file.list().length;
        //        }
        return 0;
    }


    public static void getFiles(String filePath) {
        File root = new File(filePath);
        File[] files = root.listFiles();
        for (File file : files) {
            if (file.isDirectory()) {
                allFileDirectory.add(file);

                getFiles(file.getAbsolutePath());
                System.out.println("???" + filePath + "?????????????????" + file.getAbsolutePath());
            } else {
                allFile.add(file);
                System.out.println("???" + filePath + "??????????" + file.getAbsolutePath());
            }
        }
    }


    public static List<File> getFileList(String filePath, final String extName) {
        List<File> fileList = new ArrayList<File>();  //  #6807 java.lang.NullPointerException
        File root = new File(filePath);
        if (root != null) {
            List<File> files = Arrays.asList(root.listFiles(new FilenameFilter() {
                @Override
                public boolean accept(File dir, String name) {
                    return name.endsWith(extName);
                }
            }));
            Collections.sort(files, new Comparator<File>() {
                @Override
                public int compare(File f1, File f2) {
                    if (f1.lastModified() == f2.lastModified())
                        return 0;
                    else
                        return (f1.lastModified() > f2.lastModified() ? -1 : 1);
                }
            });
            return files;
        } else {
            return null;
        }
    }


    public static void saveFileString(String fileName, String writestr) {
        try {
            FileOutputStream fos = new FileOutputStream(fileName);
            BufferedOutputStream bos = new BufferedOutputStream(fos);
            bos.write(writestr.getBytes());
            bos.close();
            fos.close();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    public static String readFileString(String fileName) {
        String res = "";
        try {
            FileInputStream fin = new FileInputStream(fileName);
            BufferedInputStream bis = new BufferedInputStream(fin);

            int length = fin.available();
            byte[] buffer = new byte[bis.available()];
            fin.read(buffer);
            res = new String(buffer);
            bis.close();
            fin.close();
        } catch (Exception e) {
            e.printStackTrace();
        }
        return res;
    }

    /**
     *
     *

     */
    public static void renameFile(String oldFilaName, String newFilaName) {
        File oleFile = new File(oldFilaName);
        File newFile = new File(newFilaName);
        oleFile.renameTo(newFile);
    }

    /**
     * @return boolean
     */
    public static void copyFile(String oldPath, String newPath) {
        try {
            int byteread = 0;
            File oldfile = new File(oldPath);
            if (oldfile.exists()) {
                InputStream inStream = new FileInputStream(oldPath);
                FileOutputStream fs = new FileOutputStream(getFile(newPath));
                byte[] buffer = new byte[2048];
                while ((byteread = inStream.read(buffer)) != -1) {
                    fs.write(buffer, 0, byteread);
                }
                inStream.close();
                fs.flush();
                fs.close();
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    /**
     * @return boolean
     */
    public static void copyFile(String oldPath, File newFile) {
        try {
            int byteread = 0;
            File oldfile = new File(oldPath);
            if (oldfile.exists()) {
                InputStream inStream = new FileInputStream(oldPath);
                FileOutputStream fs = new FileOutputStream(newFile);
                byte[] buffer = new byte[2048];
                while ((byteread = inStream.read(buffer)) != -1) {
                    fs.write(buffer, 0, byteread);
                }
                inStream.close();
                fs.flush();
                fs.close();
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    /**
     * @param assetPath
     * @param newPath
     */
    public static void copyAssetsFile(Context ctx, String assetPath, String newPath) {
        InputStream is;
        try {
            int bytesum = 0;
            int byteread = 0;
            is = ctx.getAssets().open(assetPath);
            FileOutputStream fs = new FileOutputStream(getFile(newPath));
            byte[] buffer = new byte[1444];
            int length;
            while ((byteread = is.read(buffer)) != -1) {
                bytesum += byteread;
                System.out.println(bytesum);
                fs.write(buffer, 0, byteread);
            }
            is.close();
        } catch (Exception e) {

            e.printStackTrace();
        }
    }

    public static void createNewFile(String filePath) {
        if (isExist(filePath)) {
            FileUtil.deleteFile(new File(filePath));
        }
        File fileDir = new File(filePath);
        fileDir.mkdirs();
    }

    public static final int SIZETYPE_B = 1;
    public static final int SIZETYPE_KB = 2;
    public static final int SIZETYPE_MB = 3;
    public static final int SIZETYPE_GB = 4;

    /**
     *
     */
    public static double getFileOrFilesSize(String filePath, int sizeType) {
        File file = new File(filePath);
        long blockSize = 0;
        try {
            if (file.isDirectory()) {
                blockSize = getFileSizes(file);
            } else {
                blockSize = getFileSize(file);
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
        return FormetFileSize(blockSize, sizeType);
    }

    /**

     */
    public static String getAutoFileOrFilesSize(String filePath) {
        File file = new File(filePath);
        long blockSize = 0;
        try {
            if (file.isDirectory()) {
                blockSize = getFileSizes(file);
            } else {
                blockSize = getFileSize(file);
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
        return FormetFileSize(blockSize);
    }

    /**
     * @return
     */
    public static long getFileSize(File file) {
        long size = 0;
        try {
            if (file.exists()) {
                FileInputStream fis = new FileInputStream(file);
                size = fis.available();
            } else {
                file.createNewFile();
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
        return size;
    }

    /**
     * @param f
     * @return
     */
    public static long getFileSizes(File f) throws Exception {
        long size = 0;
        File flist[] = f.listFiles();
        for (int i = 0; i < flist.length; i++) {
            if (flist[i].isDirectory()) {
                size = size + getFileSizes(flist[i]);
            } else {
                size = size + getFileSize(flist[i]);
            }
        }
        return size;
    }

    /**
     * @param fileS
     * @return
     */
    public static String FormetFileSize(long fileS) {
        DecimalFormat df = new DecimalFormat("#.00");
        String fileSizeString = "";
        String wrongSize = "0B";
        if (fileS == 0) {
            return wrongSize;
        }
        if (fileS < 1024) {
            fileSizeString = df.format((double) fileS) + "B";
        } else if (fileS < 1048576) {
            fileSizeString = df.format((double) fileS / 1024) + "KB";
        } else if (fileS < 1073741824) {
            fileSizeString = df.format((double) fileS / 1048576) + "MB";
        } else {
            fileSizeString = df.format((double) fileS / 1073741824) + "GB";
        }
        return fileSizeString;
    }

    /**
     * @param fileS
     * @param sizeType
     * @return
     */
    public static double FormetFileSize(long fileS, int sizeType) {
        DecimalFormat df = new DecimalFormat("#.00");
        double fileSizeLong = 0;
        switch (sizeType) {
            case SIZETYPE_B:
                fileSizeLong = Double.valueOf(df.format((double) fileS));
                break;
            case SIZETYPE_KB:
                fileSizeLong = Double.valueOf(df.format((double) fileS / 1024));
                break;
            case SIZETYPE_MB:
                fileSizeLong = Double.valueOf(df.format((double) fileS / 1048576));
                break;
            case SIZETYPE_GB:
                fileSizeLong = Double.valueOf(df
                        .format((double) fileS / 1073741824));
                break;
            default:
                break;
        }
        return fileSizeLong;
    }

    /**
     * @param b
     * @param outputFile
     * @return
     */
    public static File getFileFromBytes(byte[] b, String outputFile) {
        File ret = null;
        BufferedOutputStream stream = null;
        try {
            ret = new File(outputFile);
            FileOutputStream fstream = new FileOutputStream(ret);
            stream = new BufferedOutputStream(fstream);
            stream.write(b);
        } catch (Exception e) {
            // log.error("helper:get file from byte process error!");
            e.printStackTrace();
        } finally {
            if (stream != null) {
                try {
                    stream.close();
                } catch (IOException e) {
                    // log.error("helper:get file from byte process error!");
                    e.printStackTrace();
                }
            }
        }
        return ret;
    }


    public static String getRealFilePath( final Context context, final Uri uri ) {
        if ( null == uri ) return null;
        final String scheme = uri.getScheme();
        String data = null;
        if ( scheme == null )
            data = uri.getPath();
        else if ( ContentResolver.SCHEME_FILE.equals( scheme ) ) {
            data = uri.getPath();
        } else if ( ContentResolver.SCHEME_CONTENT.equals( scheme ) ) {
            Cursor cursor = context.getContentResolver().query( uri, new String[] { MediaStore.Images.ImageColumns.DATA }, null, null, null );
            if ( null != cursor ) {
                if ( cursor.moveToFirst() ) {
                    int index = cursor.getColumnIndex( MediaStore.Images.ImageColumns.DATA );
                    if ( index > -1 ) {
                        data = cursor.getString( index );
                    }
                }
                cursor.close();
            }
        }
        return data;
    }
}
